home *** CD-ROM | disk | FTP | other *** search
- #include <tos.h>
- #include <linea.h>
- #include <vdi.h> /* nur für MFDB!! */
- #include <stdlib.h>
-
- #include "sdump.h"
-
- #ifndef GEMDUMP
- extern SCREEN_DUMP dump;
- # define inst dump.inst
- # define scr_nr dump.nr
- #else
- extern INST inst;
- extern int scr_nr;
- #endif
-
- /*
- fehlerbehandlung
- */
- int xerr;
-
- int h_error(long err,long z)
- {
- if ( err<0L || ((z!=0L)&&(err!=z) ) ) {
- xerr=(int)err;
- if ( err>0l )
- xerr=-1000;
- return 1;
- }
- return 0;
- }
-
- /*
- gepufferte schreibroutinen
- */
- int f_id,z; /* f_id: file-id, z: schreibpostiotion im puffer */
- char *w_buf; /* zeigt auf puffer der größe BUF_SIZE */
- static void init_write(char *puffer)
- {
- w_buf=puffer;
- z=0;
- }
-
- static int write_byte(char byte) /* schreibe ein byte gepuffert */
- {
- w_buf[z++]=byte;
- if ( z==BUF_SIZE ) {
- if ( h_error(Fwrite(f_id,BUF_SIZE,w_buf),BUF_SIZE) )
- { Fclose(f_id); return 1; }
- z=0;
- }
- return 0;
- }
-
- /* schreibe block gepuffert */
- static int write_block(long len,char *block)
- {
- long i;
- for ( i=0; i<len; i++,block++ )
- if ( write_byte(*block) )
- return 1;
- return 0;
- }
-
- /* schreibe restpuffer & schließe datei */
- static int close_write(void)
- {
- if ( z!=0 ) {
- if ( h_error(Fwrite(f_id,(long)z,w_buf),(long)z) )
- { Fclose(f_id); return 1; }
- z=0;
- }
- return 0;
- }
-
- /* schreibe ungepackte daten (für img) */
- static int write_upk(int len,char *unpacked)
- {
- if ( write_byte(0x80) || write_byte(len) )
- return 1;
- return write_block(len,unpacked);
- }
-
- /*
- initialisiere strukturen für xIMG-Datei
- */
- static void init_img(SAVE_IMG *img,IMG_HEAD *head,MFDB *mfdb,int w,int h,char *line,int llen,int pix_wid,int pix_hght)
- {
- img->line=line; /* zeilenbuffer */
- img->pic_line=img->pic_buf=mfdb->fd_addr; /* bildbuffer */
- img->flag=img->line_nr=0; /* laufvariable */
-
- img->bwid=w/8; /* ausmaße */
- if ( w%8 )
- img->bwid++;
- if ( img->bwid>llen/mfdb->fd_nplanes )
- img->bwid=llen/mfdb->fd_nplanes;
- img->hght=h;
-
- img->pic_bwid=mfdb->fd_wdwidth*2; /* breite der bitmap */
- if ( !mfdb->fd_stand )
- img->pic_bwid*=mfdb->fd_nplanes;
-
- img->plane_size=(long)mfdb->fd_wdwidth*2l*mfdb->fd_h;
-
- img->standard=mfdb->fd_stand;
-
- head->ver_num=0; /* dateiheader */
- head->head_len=8;
- head->pat_len=2;
-
- head->pix_wid=(pix_wid==-1)?0x174:pix_wid;
- head->pix_hght=(pix_hght==-1)?0x174:pix_hght;
- img->planes=mfdb->fd_nplanes;
-
- head->plane_num=mfdb->fd_nplanes;
- head->pix_num=w;
- if ( w>llen/mfdb->fd_nplanes*8 )
- head->pix_num=llen/mfdb->fd_nplanes*8;
- head->scan_num=h;
- }
-
- /*
- lese/vergleiche zeile
- */
- static int get_line(SAVE_IMG *img,int mode)
- {
- char *h1,*h2;
- int cnt,i,ii;
-
- if ( img->flag==-1 || (img->flag && mode) )
- return 0;
-
- h1=img->line;
-
- if ( !img->standard ) { /* st-screen format */
- int offset;
- if ( mode ) { /* nur testen */
- for ( i=0,offset=0; i<img->planes; i++,offset+=2 ) {
- for ( cnt=0,h2=img->pic_line+offset; cnt<img->bwid; h2+=2*(img->planes-1) )
- for ( ii=0; ii<2 && cnt<img->bwid; ii++,cnt++ )
- if ( *h1++!=*h2++ )
- return 0;
- }
- }
- else { /* kopieren */
- for ( i=0,offset=0; i<img->planes; i++,offset+=2 ) {
- for ( cnt=0,h2=img->pic_line+offset; cnt<img->bwid; h2+=2*(img->planes-1) )
- for ( ii=0; ii<2 && cnt<img->bwid; ii++,cnt++ )
- *h1++=*h2++;
- }
- img->flag=0;
- }
- }
- else { /* standard format */
- long offset;
- if ( mode ) { /* nur testen */
- for ( i=0,offset=0l; i<img->planes; i++,offset+=img->plane_size ) {
- for ( cnt=0,h2=img->pic_line+offset; cnt<img->bwid; cnt++ )
- if ( *h1++!=*h2++ )
- return 0;
- }
- }
- else { /* kopieren */
- for ( i=0,offset=0l; i<img->planes; i++,offset+=img->plane_size ) {
- for ( cnt=0,h2=img->pic_line+offset; cnt<img->bwid; cnt++ )
- *h1++=*h2++;
- }
- img->flag=0;
- }
- }
-
- img->pic_line+=img->pic_bwid;
- img->line_nr++;
- if ( img->line_nr==img->hght ) { /* ende erreicht */
- img->flag=-1;
- }
- return 1;
- }
-
- /*
- schreibe block (0,0,wid,hght) aus 'buffer' in xIMG-Datei 'name'
- 'col' zeigt auf farbtabelle, 'xflag' gibt an ob IMG (DO_XIMG false) oder
- xIMG (DO_XIMG true)
- geschrieben werden soll (falls xflag==0 ist col redundand und wird nicht beachtet)
-
- falls GEMDUMP nicht (mit -DGEMDUMP) in den compileroptionen gesetzt ist
- wird bei gesetztem xflag und 'col==0l' statt der farbtabelle in col
- die farben via xbios ermittelt und geschrieben!
-
- rückgabewert: 0 ok
- <0 gemdos/bios fehlernummer oder
- -1000 für 'zu wenig daten geschrieben bei fwrite'
- */
- #define DO_XIMG ((header.plane_num>1 && xflag&1) || xflag&2)
- /* true -> schreibe ximg, false -> kein ximg */
- int do_store_img(char *name,MFDB *buffer,int wid,int hght,COLOR *col,int xflag,int pix_wid,int pix_hght)
- {
- char *line;
- static char lline[MAX_LINE_LEN],unpacked[256];
- static char buf[BUF_SIZE];
- static IMG_HEAD header;
- static SAVE_IMG img;
- int cnt,len,i;
- char *h;
-
- if ( h_error((long)(f_id=Fcreate(name,0)),0L) )
- return xerr;
-
- init_write(buf); /* init für write_byte */
-
- line=lline;
-
- init_img(&img,&header,buffer,wid,hght,line,MAX_LINE_LEN,pix_wid,pix_hght);
-
-
- /*
- header modifizieren für ximg
- */
- if ( DO_XIMG )
- header.head_len+=3+3*(1<<header.plane_num);
-
- /*
- header schreiben
- */
- for ( h=(char*)&header,len=0; len<16; len++,h++ )
- if ( write_byte(*h) )
- { Fclose(f_id); return xerr; }
-
-
- /*
- ximg schreiben
- */
- if ( DO_XIMG ) {
- if ( write_byte('X') || write_byte('I') || write_byte('M') || write_byte('G')
- || write_byte(0) || write_byte(0) )
- { Fclose(f_id); return xerr; }
- len=(int)sizeof(COLOR)*(1<<header.plane_num);
-
- #ifndef GEMDUMP
- if ( col ) {
- #endif
- for ( h=(char*)col; len>0; h++,len-- )
- if ( write_byte(*h) )
- { Fclose(f_id); return xerr; }
- #ifndef GEMDUMP
- }
- else { /* farben nicht gesetzt -> via xbios holen */
- COLOR col;
- int i,c;
- for ( i=0; i<(1<<buffer->fd_nplanes); i++ ) {
- c=Setcolor(i,-1);
- col.red=(((c>>8)&7)*1000)/7;
- col.green=(((c>>4)&7)*1000)/7;
- col.blue=((c&7)*1000)/7;
- for ( h=(char*)&col,len=(int)sizeof(COLOR); len>0; h++,len-- )
- if ( write_byte(*h) )
- { Fclose(f_id); return xerr; }
- }
- }
- #endif
- }
-
- /*
- schreibe graphikdaten
- */
- while ( get_line(&img,0) ) {
- cnt=1;
- while ( cnt<255 && get_line(&img,1) ) { /* gleiche zeilen? */
- cnt++;
- }
- if ( cnt>1 ) { /* zeilenwiederholung eintragen */
- if ( write_byte(0) || write_byte(0) || write_byte(0xFF) || write_byte(cnt) )
- { Fclose(f_id); return xerr; }
- }
-
- h=line; /* zeile schreiben */
- for ( i=0; i<img.planes; i++ ) {
- for ( len=cnt=0; cnt<img.bwid; ) {
- if ( (*h==0 && *(h+1)==0) || (*h==0xFF && *(h+1)==0xFF) ) {
- char muster; /* solid run */
- if ( len ) {
- if ( write_upk(len,unpacked) )
- { Fclose(f_id); return xerr; }
- }
- len=0;
- muster=*h;
- while ( *h==muster && cnt<img.bwid && len<63 )
- len++,cnt++,h++;
- if ( muster!=0 )
- len|=128;
- if ( write_byte(len) )
- { Fclose(f_id); return xerr; }
- len=0;
- }
- else if ( cnt+5<img.bwid && *h==*(h+1) && *h==*(h+2) && *h==*(h+3) && *h==*(h+4) ) {
- char muster_lo,muster_hi; /* pattern run */
- char *h1,*h2;
- if ( len ) {
- if ( write_upk(len,unpacked) )
- { Fclose(f_id); return xerr; }
- }
- len=0;
- h1=h;
- h2=h1+1;
- muster_lo=*h1;
- muster_hi=*h2;
- while ( *h1==muster_lo && *h2==muster_hi && cnt<img.bwid-1 && len<255 )
- len++,cnt+=2,h1+=2,h2+=2;
- if ( write_byte(0) || write_byte(len) || write_byte(muster_lo) || write_byte(muster_hi) )
- { Fclose(f_id); return xerr; }
- h=h1;
- len=0;
- }
- else { /* unpacked */
- unpacked[len++]=*h++;
- cnt++;
- if ( len==255 ) {
- if ( write_upk(len,unpacked) )
- { Fclose(f_id); return xerr; }
- len=0;
- }
- }
- }
- if ( len ) {
- if ( write_upk(len,unpacked) )
- { Fclose(f_id); return xerr; }
- }
- }
- }
-
- if ( close_write() )
- { return xerr; }
- h_error((long)Fclose(f_id),0L);
-
- return 0;
- }
-
- /*
- erzeuge namen für screendump
- scr_nr ist zähler für bildnummer
- */
- void make_name(char *name)
- {
- char *d,*s,nr[10];
-
- for ( d=name,s=inst.file; *s!=0; ) /* kopiere dump_file nach name */
- *d++=*s++;
- itoa(scr_nr,nr,10); /* don't use sprintf here (exceeds prg-size) */
- scr_nr++;
- for ( s=nr; *s!=0; ) /* strcat nr an name */
- *d++=*s++;
- for ( s=".IMG"; *s!=0; )
- *d++=*s++;
- *d=0;
- }
-
- #ifndef GEMDUMP /* verwaltet zugriff auf fullscreen */
- /* mittels scr->fd_addr==0l */
- /* liest parameter via XBIOS (Logbase) */
- /* Vdiesc/LineA-Variable */
- /* dx==0 -> fullscreen */
- /* dy==0 -> fullscreen */
- int store_img(char *name,MFDB *scr,int dx,int dy,COLOR *col,int xflag,int pix_wid,int pix_hght)
- {
- if ( scr->fd_addr==0l ) {
- linea_init();
- scr->fd_addr=Logbase();
- scr->fd_wdwidth=Vdiesc->bytes_lin/2/Linea->v_planes;
- /* notwendig für overscan (dann ungleich dx/16!!) */
- scr->fd_w=Vdiesc->v_rez_hz;
- scr->fd_h=Vdiesc->v_rez_vt;
- scr->fd_nplanes=Linea->v_planes;
- scr->fd_stand=0; /* geräteformat */
- }
- if ( dx==0 )
- dx=scr->fd_w;
- if ( dy==0 )
- dy=scr->fd_h;
-
- if ( do_store_img(name,scr,dx,dy,col,xflag,pix_wid,pix_hght) )
- return xerr;
-
- return 0;
- }
-
- void do_althelp(void) /* aufruf von althelp */
- {
- MFDB scr;
- char name[64];
-
- make_name(name);
-
- scr.fd_addr=0l; /* access screen */
- store_img(name,&scr,0,0,0l,inst.ximg,-1,-1);
- }
- #endif
-
-